using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using System.Xml.Serialization;
using System.IO;

namespace WiMo.Games.ZuneHD
{
    /// <summary>
    /// Default implementation of a state manager, all strings are stored in their own file
    /// pretty sure there is a better mechanism for saving key-value pairs, but this is a 
    /// reference implementation.
    /// </summary>
    public class StateManager : IStateManager
    {
        private const string STR_StorageContainer = "WiMoGFGameStorage";
        IAsyncResult _result;
        IGameEngine _engine;

        private string Root
        {
            get
            {
                if (_engine.Game == null)
                    throw new NullReferenceException("You must initialize the Game property on the GameEngine before accessing storage values.");

                var assembly = _engine.Game.GetType().Assembly;
                return String.Format(@"WiMoGF.{0}", assembly.FullName.Substring(0, assembly.FullName.IndexOf(',')));
            }
        }


        public StateManager(IGameEngine engine)
        {
            _result = Guide.BeginShowStorageDeviceSelector(null, null);
            _engine = engine;
        }

        public void Store(string key, string value)
        {
            if (_result.IsCompleted)
            {
                var device = Guide.EndShowStorageDeviceSelector(_result);
                if (device != null && device.IsConnected)
                {
                    // Open a storage container.
                    using (var container = device.OpenContainer(STR_StorageContainer))
                    {

                        using (var stream = File.Open(GetFileName(container.Path, key), FileMode.OpenOrCreate, FileAccess.Write))
                        {
                            XmlSerializer serializer = new XmlSerializer(typeof(String));
                            serializer.Serialize(stream, value);
                            return;
                        }

                    }
                }
            }

            throw new NullReferenceException("Could not get storage device.");
        }

        private string GetFileName(string path, string key)
        {
            return Path.Combine(path, string.Format("{1}.{2}.sav", path, Root, key));
        }

        public string Get(string key, string defaultValue)
        {
            if (_result.IsCompleted)
            {
                var device = Guide.EndShowStorageDeviceSelector(_result);
                if (device != null && device.IsConnected)
                {
                    // Open a storage container.
                    using (var container = device.OpenContainer(STR_StorageContainer))
                    {
                        var fileName = GetFileName(container.Path, key);
                        System.Diagnostics.Debug.WriteLine("Attempt to get value from-> " + fileName);
                        try
                        {
                            using (var stream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                            {

                                if (stream != null)
                                {
                                    // Read the data from the file.
                                    XmlSerializer serializer = new XmlSerializer(typeof(string));
                                    return (String)serializer.Deserialize(stream);
                                }
                                else
                                    return defaultValue;
                            }
                        }
                        catch(System.Exception)
                        {
                            return defaultValue;
                        }
                    }
                }
            }

            throw new NullReferenceException("Could not get storage device.");
        }

        public void ClearAll()
        {
            throw new NotImplementedException();
        }
    }
}